<template>
  <section class="xm-content xm-role">
    <el-form
      ref="form"
      v-loading="box_loading"
      :model="form"
      :rules="rules"
      size="mini"
      label-width="100px"
      inline-message
    >
      <el-form-item label="角色名称" prop="name">
        <el-input v-model="form.name" clearable placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item label="角色标记" prop="sign">
        <el-input v-model="form.sign" clearable placeholder="请输入角色标记" />
      </el-form-item>
      <el-form-item label="机器" prop="manchines">
        <el-select
          v-model="form.manchines"
          @change="changeSelect"
          clearable
          collapse-tags
          filterable
          multiple
          placeholder="请多选机器"
        >
          <el-option key="selectAll" label="全部" value="selectAll"></el-option>
          <el-option
            v-for="(item, index) in manchinesList"
            :key="index"
            :value="String(item.id)"
            :label="item.name"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="授权">
        <el-tree
          ref="mytree"
          v-model="form.menus"
          :data="superMenu"
          node-key="id"
          :props="{ label: 'name' }"
          default-expand-all
          show-checkbox
          :check-on-click-node="true"
          :check-strictly="true"
          :expand-on-click-node="false"
          @check="nodeClick"
        >
          <span slot-scope="{ node, data }" class="custom-tree-node">
            <span style="width: 200px;">
              {{ node.label }}
              <span v-if="data.level == 0" style="color: green;">[目录]</span>
              <span v-if="data.level == 1" style="color: green;">[菜单]</span>
            </span>
            <span
              ><span v-if="data.level == 2" style="color: #666;"
                >按钮</span
              ></span
            >
          </span>
        </el-tree>
      </el-form-item>

      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="form.status">
          <el-radio label="1">正常</el-radio>
          <el-radio label="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="备注">
        <el-input
          v-model="form.remark"
          type="textarea"
          clearable
          placeholder="请输入备注内容"
          maxlength="300"
          show-word-limit
          rows="4"
        />
      </el-form-item>
    </el-form>
    <div class="xm-footer">
      <el-button
        type="primary"
        size="mini"
        :loading="btn_loading"
        @click="saves('form')"
        >确 定</el-button
      >
      <el-button type="info" size="mini" @click="close">关 闭</el-button>
    </div>
  </section>
</template>

<script>
import {
  editRole,
  addRole,
  getMenuList,
  getMaschines,
  getRoleMenus, //角色授权查询
} from '@/api/user'
export default {
  props: {
    layerid: {
      default: 0,
    },
    row: {
      default: {},
    },
  },
  data() {
    return {
      box_loading: false,
      btn_loading: false,
      form: {
        // status: 'normal',
        name: '', //名称
        sign: '', //标记
        remark: '', //	备注
        manchines: '', //	机器ids
        menus: [], //	授权菜单
      },
      superMenu: [], // 总的权限树
      rules: {
        name: [{ required: true, message: '必填', trigger: 'blur' }],
        sign: [{ required: true, message: '必填', trigger: 'blur' }],
        status: [{ required: true, message: '必选', trigger: 'change' }],
      },
      manchinesList: [],
      checkedDataArr: [],
      selectAll: false,
    }
  },
  mounted() {
    this.getMaschines()
    if (this.row.id) {
      this.form = JSON.parse(JSON.stringify(this.row))
      if (this.form.manchines) {
        this.form.manchines = this.form.manchines.split(',')
      }
      if (this.form.status) {
        this.form.status = String(this.form.status)
      }
    }
    this.getSuperMenu()
  },
  methods: {
    changeSelect(value) {
      //  selectAll 为true 的时候，就走全选分支，全选后出现的情况就是取消权限
      if (this.selectAll) {
        this.selectAll = false
        if (value.indexOf('selectAll') > -1) {
          this.form.manchines = value.filter((p) => p != 'selectAll')
        } else {
          this.form.manchines = []
        }
      } else {
        //   是否点击了‘全选’选项
        if (value.indexOf('selectAll') > -1) {
          // 有‘全选’选项，则将‘全部’和其他值放置一块
          const optionsValue = []
          this.manchinesList.forEach((item) => {
            optionsValue.push(item.id.toString())
          })
          this.form.manchines = ['selectAll', ...optionsValue]
          this.selectAll = true
        } else {
          // 若是勾选选择的长度和提供的选项长度是一样的，则是 ‘全选’
          if (value.length === this.manchinesList.length) {
            const optionsValue = []
            this.manchinesList.forEach((item) => {
              optionsValue.push(item.id.toString())
            })
            this.form.manchines = ['selectAll', ...optionsValue]
            this.selectAll = true
          } else {
            //   都是单选
            this.form.manchines = value
          }
        }
      }
      // 真实的勾选值
      const realSelect = this.form.manchines.filter(
        (item) => item != 'selectAll'
      )
    },
    // 初始化菜单总树
    async getSuperMenu() {
      this.box_loading = true
      const { data } = await getMenuList({})
      this.box_loading = false
      this.superMenu = data.children
      this.$nextTick(() => {
        this.getRoleMenus(this.row.id)
      })
    },
    async getRoleMenus(id) {
      const res = await getRoleMenus(id)
      this.form.menus = res.data.children
      //选中数据id  递归回填
      this.$refs.mytree.setCheckedKeys(this.getMenusId(this.form.menus))
    },
    getMenusId(data) {
      for (var i = 0; i < data.length; i++) {
        if (data[i].checked == true || data[i].checked == 'true') {
          const objId = data[i].id
          if (data[i].children) {
            this.getMenusId(data[i].children)
          }
          this.checkedDataArr.push(objId)
        }
      }
      return this.checkedDataArr
    },
    async getMaschines() {
      const res = await getMaschines({})
      this.manchinesList = res.data
    },
    getCheckedNodes() {
      // this.$refs.mytree.setCheckedKeys([1]);
    },
    // 点击节点时才触发(选中取消都触发)：点节点行或复选框都行，只要是手点的都行，可如果通过接口去选择，回填等情况就不会触发
    nodeClick(data, complexData) {
      const tmplt = JSON.parse(JSON.stringify(this.superMenu)) // 取出数据库的菜单总树
      let oldTree = this.$refs.mytree.getCheckedKeys() // 上一步的旧树
      let newTree = []
      // 通过判断complexData变长或者短(保留上次的记录来比较)，间接判断出被点的data是选中还是取消
      if (complexData.checkedKeys.includes(data.id)) {
        // 一、如果选中，那此节点和其所有父节点自动选中
        const tgt = []
        tgt.push(data.id)
        newTree = this.getFather(tmplt, tgt, data.parentId) // 只是拿到你点的那个节点所影响的一个分支，和旧树叠加去重即可
        oldTree.push(...newTree)
        this.$refs.mytree.setCheckedKeys(Array.from(new Set(oldTree)))
      } else {
        // 二、如果取消，那此节点和其所有子节点自动取消
        const son = []
        son.push(data.id)
        newTree = this.getSon(data.children, son)
        oldTree = oldTree.filter((item) => newTree.indexOf(item) === -1)
        this.$refs.mytree.setCheckedKeys(oldTree)
      }
    },
    // 递归一：取节点和节点父级
    getFather(tmplt, tgt, parentId) {
      if (parentId === null) return tgt
      tmplt.forEach((item) => {
        if (item.id == parentId) {
          // 这喊后端改下，本人强迫症癖好全等
          tgt.push(item.id)
          this.getFather(
            JSON.parse(JSON.stringify(this.superMenu)),
            tgt,
            item.parentId
          ) // 哈哈哈，这千万别用tmplt传进去，你会发现找不出来
        } else if (item.children && String(item.children) !== '') {
          this.getFather(item.children, tgt, parentId)
        }
      })
      return tgt
    },
    // 递归二：取节点和节点子集
    getSon(children, son) {
      if (!children || String(children) === '') {
        return son
      } else {
        children.forEach((item) => {
          son.push(item.id)
          this.getSon(item.children, son)
        })
      }
      return son
    },

    /* 添加、编辑 */
    saves(formName) {
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          this.form.manchines = this.form.manchines.filter(
            (item) => item != 'selectAll'
          )
          const obj = JSON.parse(JSON.stringify(this.form))
          obj.menus = this.$refs.mytree.getCheckedKeys()
          if (obj.manchines) {
            obj.manchines = obj.manchines.join(',')
          }
          this.btn_loading = true
          let res = ''
          if (obj.id) {
            res = await editRole(obj)
          } else {
            res = await addRole(obj)
          }
          this.btn_loading = false
          if (res.status && res.status != 200) {
            // this.$message({ message: res.data.message, type: 'error' })
            return false
          }
          Object.assign(this.$data, this.$options.data())
          this.$layer.close(this.layerid)
          this.$parent.getList()
          this.$message({ message: '操作成功', type: 'success' })
          // Object.assign(this.$data.form, this.$option.data().form)
        } else {
          this.$refs[formName].validate()
        }
      })
    },
    close() {
      this.$layer.close(this.layerid)
    },
  },
}
</script>
<style>
.el-upload-list__item {
  transition: none !important;
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.el-dialog .el-dialog__footer {
  z-index: 100;
}
</style>
